import java.util.*;
import java.io.*;

/**
 * Creates the in-depth section by taking translated !open/!shut
 * comments and inserting the code they surround from file.
 * 
 * @author James Stanier
 */
public class InDepthSectionCreator {
	private String output;
	private String fileName;
	private ArrayList<LaTeXCommentToken> translatedComments;
	private BufferedReader br;
	private Stack<String> scopeStack;

	/**
	 * Constructor.
	 * @param s The filename of the source file.
	 * @param a The array of comment tokens for that file.
	 */
	public InDepthSectionCreator(String s, ArrayList<LaTeXCommentToken> a) {
		try {
			scopeStack = new Stack<String>();
			fileName = s;
			translatedComments = a;
			output = "";
		}
		catch(Exception e) {
			System.err.println(e);
			e.printStackTrace();
		}
	}

	/**
	 * Inserts all code blocks from file between their
	 * !open and !shut comments.
	 * @throws Exception
	 */
	public void insertCode() throws Exception {

		int readFrom;
		int readTo;

		for(int i = 0; i < translatedComments.size(); ) {

			LaTeXCommentToken ct = translatedComments.get(i);

			if(ct.isOpen()) {
				output += ct.getCode();
				readFrom = ct.getLineNumber();

				i++;
				ct = translatedComments.get(i);
				readTo = ct.getLineNumber();


				try {
					int counter = -1;
					br = new BufferedReader(new FileReader(fileName));
					String current = br.readLine();
					String temp = "";
					while(current != null) {

						if(counter > readFrom && counter < readTo) {

							temp += current + "\n";
						}
						counter++;
						current = br.readLine();
					}
					// Process string
					output += processCode(temp);

					if(!ct.isOpen()) {
						output += ct.getCode();
					}
					i++;
				}
				catch(Exception e) {
					System.err.println(e);
					e.printStackTrace();
				}
			}
			else {

				throw new Exception("!shut before !open");

			}
		}
		try {
			br.close();
		}
		catch(Exception e) {
			System.err.println(e);
			e.printStackTrace();
		}
	}

	/**
	 * Adds a variable index/grid to the output
	 * if it has been requested.
	 */
	public void addVariableIndex(String s) {
		output += "\n" + s;
	}

	/**
	 * Get the finished output.
	 * @return Translated output.
	 */
	public String getOutput() {
		return output;
	}

	/**
	 * Process the code for proper LaTeX
	 * indentation, etc.
	 * 
	 * @param s The code to be processed.
	 * @return The processed code in LaTeX.
	 */
	public String processCode(String s) {
		scopeStack = new Stack<String>();
		String output = "";
		if(s.contains(";*/")) {
			String[] sa = null;
			sa = s.split("/");
			s = sa[1];
		}
		if(s.contains("/*;")) {
			String[] sa = null;
			sa = s.split("/");
			s = sa[0].trim();
		}
		s = s.trim();
		output += "\\begin{verbatim}\n";

		int counter = 0;
		while(counter < s.length()) {
			if(s.charAt(counter) == '\n') {

				output += "\n";
				counter++;

				if(s.charAt(counter) =='\u0009') {


					if(scopeStack.size() > 0) {
						for(int i = 0; i < scopeStack.size(); i++) {
							output += "   ";
						}
					}

					while(Character.isWhitespace(s.charAt(counter))) {
						counter++;
					}
				}

			}
			else {
				if(s.charAt(counter) == '{' || s.charAt(counter) == '}') {

					if(s.charAt(counter) == '{') {
						scopeStack.push("{");
					}
					else if(s.charAt(counter) == '}') {
						scopeStack.pop();
						if(output.endsWith("   ")) {
							output = output.substring(0, output.length()-3);
						}
					}

				}
				output += s.charAt(counter);
				counter++;
			}
		}

		output += "\n\\end{verbatim}\n";
		return output;

	}
}
